#include <fibthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define err_check(func, errval) \
	do { \
	if (errval) { fprintf(stderr, "(%s): %s\n", func, strerror(errval)); exit(EXIT_FAILURE); } \
	} while(0)

int g_val = 0;
fibthread_mutex_t mutex = FIBTHREAD_MUTEX_INITIALIZER;

void *thread_func1(void *arg);
void *thread_func2(void *arg);

int main(void)
{
	fibthread_t thread1, thread2;
	int retval;

	retval = fibthread_create(&thread1, NULL, thread_func1, NULL);
	err_check("fibthread_create", retval);

	retval = fibthread_create(&thread2, NULL, thread_func2, NULL);
	err_check("fibthread_create", retval);

	retval = fibthread_join(thread2, NULL);
	err_check("fibthread_join", retval);

	retval = fibthread_join(thread1, NULL);
	err_check("fibthread_join", retval);

	return 0;
}

void *thread_func1(void *arg) {
	int retval;
	int tmpval;

	retval = 0;
	while (1) {
		retval = fibthread_mutex_lock(&mutex);
		err_check("fibthread_mutex_lock", retval);

		printf("<thread_func1> g_val => %d\n", tmpval = ++g_val);

		retval = fibthread_mutex_unlock(&mutex);
		err_check("fibthread_mutex_unlock", retval);

		if (tmpval > 50)
			break;

		fibthread_yield();

	}

	return NULL;
}

void *thread_func2(void *arg) {
	int retval;
	int tmpval;

	retval = 0;

	while (1) {
		retval = fibthread_mutex_lock(&mutex);
		err_check("fibthread_mutex_lock", retval);

		printf("<thread_func2> g_val => %d\n", tmpval = ++g_val);

		retval = fibthread_mutex_unlock(&mutex);
		err_check("fibthread_mutex_unlock", retval);

		if (tmpval > 50)
			break;

		fibthread_yield();
	}

	return NULL;
}
